package main.alarms;

import main.help.*;
import java.util.ArrayList;
import java.util.Random;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.XmlResourceParser;

import java.lang.Math;

import com.google.gson.Gson;
import java.util.Date;

import org.xmlpull.v1.XmlPullParserException;

public class AlarmsManager extends Activity {
	public static final int MAX_ALARMS_NUM = 1000; // the max num of alarms can
													// create
	public static final int VIBRATE_ENABLE = 1; // vibrate
	public static final int VIBRATE_UNABLE = 0;

	public static final int CONTROL_IF_ALARM_YES = 1;// 在操作关闭方式时是否继续闹铃选项
	public static final int CONTROL_IF_ALARM_NO = 0;

	public static final int SOUND_TYPE_RING = 1;// ring
	public static final int SOUND_TYPE_SONG = 2;// song
	public static final int SOUND_TYPE_SLIENT = 3;// slient

	public static final int SOUND_TRANS_TYPE_INC = 1;// increase
	public static final int SOUND_TRANS_TYPE_STA = 2;// no increase

	public static final int ALARM_TYPE_ALLTIME = 1;// alarm all the time
	public static final int ALARM_TYPE_INTERVAL = 2;// interval

	public static final int ALARM_CLOSE_TYPE_POWER = 1;// on power on
	public static final int ALARM_CLOSE_TYPE_SHARK = 2;// shark the phone
	public static final int ALARM_CLOSE_TYPE_LIGHT_SCREEN = 3;// light the
																// screen
	public static final int ALARM_CLOSE_TYPE_MATH = 4;// solve math problem
	public static final int ALARM_CLOSE_TYPE_VERIFY_CODE = 5;// use Verification
																// code
	public static final int ALARM_CLOSE_TYPE_VERIFY_LOCK = 6;// unlock the phone

	private ArrayList<AlarmCloseMthodConf> alarmCloseTypeSupport;
	private ArrayList<AlarmInfo> infos=null;
	private Context context;
	private SharedPreferences setting;
	private SharedPreferences.Editor settingEditor;
	private Random rand=new Random(MAX_ALARMS_NUM);
	//
	public AlarmsManager(Activity a) {
		this.context = a;
		this.setSupportAlarmCloseType();
		this.setting = this.context.getSharedPreferences("alarms", MODE_PRIVATE);
		this.settingEditor = setting.edit();
		
		//mei
		//this.removeAllAlarms();

	}

	// get support alarm close method
	public ArrayList<AlarmCloseMthodConf> getSupportAlarmCloseType() {
		return this.alarmCloseTypeSupport;
	}

	//@SuppressWarnings("unchecked")
	private boolean setSupportAlarmCloseType() {
		try {
			XmlResourceParser xmlParser = this.context.getResources().getXml(
					R.xml.alarm_close_method);
			try {
				int eventType = xmlParser.getEventType();
				ArrayList<AlarmCloseMthodConf> objs = new ArrayList<AlarmCloseMthodConf>();
				while (eventType != XmlResourceParser.END_DOCUMENT) {
					if (eventType == XmlResourceParser.START_TAG) {
						String strName = xmlParser.getName();
						if (strName.equals("method")) {

							AlarmCloseMthodConf obj = new AlarmCloseMthodConf();
							obj.name = xmlParser
									.getAttributeValue(null, "name");
							obj.className = xmlParser.getAttributeValue(null,
									"className");
							obj.type = xmlParser.getAttributeIntValue(null,
									"type", 0);
							objs.add(obj);
						}
					}
					eventType = xmlParser.next();

				}
				this.alarmCloseTypeSupport=objs;
			} catch (XmlPullParserException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			// Gson gson = new Gson();
			// ArrayList<AlarmCloseMthodConf> objs = gson.fromJson(br,
			// ArrayList.class);
			// //TODO 类型转换
			// this.alarmCloseTypeSupport=objs;
			return true;
		} catch (Exception e) {
			return false;
		}

	}

	private int genAlarmId() {
		return this.rand.nextInt(MAX_ALARMS_NUM)+(int)((double)MAX_ALARMS_NUM*Math.random());
	}

	// add new alarms to store
	private boolean editAlarmStore(AlarmInfo info) {
		Gson gson = new Gson();
		String json = gson.toJson(info);
		String alarmsAll = this.setting.getString("alarmsAll", "");
		
		String[] alarmsId = alarmsAll.split(",");
		if (alarmsAll==""||alarmsId.length == 0) {
			alarmsAll += info.id;
		} else if (!Help.inArray(info.id, alarmsId)) {
			alarmsAll += "," + info.id;
		}
		this.settingEditor.putString("alarmsAll", alarmsAll);
		this.settingEditor.putString("alarms_" + info.id, json);
		this.settingEditor.commit();
		// Class c=Class.forName("Object");
		// c.newInstance();
		return true;
	}

	private boolean removeAlarmStore(int alarmId) {
		String alarmsAll = this.setting.getString("alarmsAll", "");
		String[] alarmsId = alarmsAll.split(",");
		ArrayList<String> alarmsIdNew = new ArrayList<String>();
		boolean idAvaliable = false;

		for (int i = 0; i < alarmsId.length; i++) {
			if (Integer.parseInt(alarmsId[i]) != alarmId) {
				alarmsIdNew.add(alarmsId[i]);
			} else {
				idAvaliable = true;
			}
		}
		if (!idAvaliable) {
			return false;
		}
		alarmsAll = "";
		int sizeLeft = alarmsIdNew.size();
		if (sizeLeft == 0) {
			alarmsAll = "";
		} else if (sizeLeft == 1) {
			alarmsAll = alarmsIdNew.get(0);
		} else {
			alarmsAll = alarmsIdNew.get(0);
			for (int i = 1; i < sizeLeft; i++) {
				alarmsAll += "," + alarmsIdNew.get(i);
			}
		}
		this.settingEditor.remove("alarmsAll" + alarmsAll);
		this.settingEditor.remove("alarms_" + alarmId);
		return true;
	}
	public boolean removeAllAlarms(){
		this.settingEditor.clear();
		this.settingEditor.commit();
		this.infos=new ArrayList<AlarmInfo>();
		return true;
	}

	// get alarms from store
	public AlarmInfo getAlarmInfo(int alarmId) {
		String json = this.setting.getString("alarms_" + alarmId, "");
		if (json == "") {
			return null;
		} else {
			Gson gson = new Gson();
			AlarmInfo info;
			info = gson.fromJson(json, AlarmInfo.class);
			return info;
		}
	}

	// add new alarms
	public boolean addNewAlarm(AlarmInfo info) {
		info.id = this.genAlarmId();
		info.enabled = true;
		if(this.infos==null){
			this.infos=new ArrayList<AlarmInfo>();
		}
		this.infos.add(info);
		this.editAlarmStore(info);
		this.enableAlarm(info.id);
		return true;
	}

	// edit an alarm
	public boolean editAlarm(int alarmId, AlarmInfo infoNew) {
		AlarmInfo infoOld = this.getAlarmInfo(alarmId);
		if (infoOld!=null) {
			return false;
		}
		this.editAlarmStore(infoNew);
		return true;
	}

	public boolean enableAlarm(int alarmId) {
		AlarmInfo infoOld =  this.getAlarmInfo(alarmId);
		if (infoOld!=null) {
			return false;
		}
		infoOld.enabled = true;
		Intent intent = new Intent(this.context, infoOld.execClass);
		PendingIntent sender = PendingIntent.getBroadcast(this.context,
				infoOld.id, intent, 0);
		AlarmManager am;
		am = (AlarmManager) this.context
				.getSystemService(Context.ALARM_SERVICE);
		am.set(AlarmManager.RTC_WAKEUP, infoOld.time.getTimeInMillis(), sender);
		this.editAlarmStore(infoOld);
		return true;
	}

	public boolean unableAlarm(int alarmId) {
		AlarmInfo infoOld = this.getAlarmInfo(alarmId);
		if (infoOld!=null) {
			return false;
		}
		infoOld.enabled = false;
		Intent intent = new Intent(this.context, infoOld.execClass);
		PendingIntent sender = PendingIntent.getBroadcast(this.context,
				infoOld.id, intent, 0);
		AlarmManager am;
		am = (AlarmManager) this.context
				.getSystemService(Context.ALARM_SERVICE);
		am.cancel(sender);
		this.editAlarmStore(infoOld);
		return false;
	}

	public ArrayList<AlarmInfo> getAllAlarmInfo() {
		if(this.infos!=null){
			return this.infos;
		}
		String alarmsAll = this.setting.getString("alarmsAll", "");
		if (alarmsAll == "") {
			this.infos=new ArrayList<AlarmInfo>();
		} else {
			String[] alarmsId = alarmsAll.split(",");
			ArrayList<AlarmInfo> infos = new ArrayList<AlarmInfo>();
			for (int i = 0; i < alarmsId.length; i++) {
				AlarmInfo info = this.getAlarmInfo(Integer.parseInt(alarmsId[i]));
				infos.add(info);
			}
			this.infos=infos;
		}
		return this.infos;

	}

	// remove alarms

	public boolean removeAlarm(int alarmId) {
		AlarmInfo infoOld = this.getAlarmInfo(alarmId);
		if (infoOld!=null) {
			return false;
		}
		this.unableAlarm(alarmId);
		this.removeAlarmStore(alarmId);
		return true;
	}

}
